﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomerService
{
    public partial class SequenceTab : System.Web.UI.UserControl
    {
        protected SalesManagerEntities _context;
        protected tblCustomer _customer;
        private tblSequenceOrderStep[][] _stepArray;
        private tblSequenceOrder[] _sequenceOrderList;
        protected tblSequenceOrder _sequenceOrder = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (lvSequenceList.SelectedIndex >= 0)
                _sequenceOrder = _sequenceOrderList[lvSequenceList.SelectedIndex];

            if (IsPostBack)
            {
                if (_sequenceOrder != null)
                {
                    if (txtCardNumber.Text != string.Empty)
                    {
                        tblAccount account;
                        if (_sequenceOrder.Account == null || _sequenceOrder.Account.GetAccountNumber(_context) != txtCardNumber.Text.Trim())
                        {
                            int?[] accountIDs = _context.spFindAccount(txtCardNumber.Text.Trim()).ToArray();

                            if (accountIDs.Length > 0)
                                account = _context.tblAccount.Find(new object[] { accountIDs[0] });
                            else
                                account = new tblAccount(_sequenceOrder);
                            _sequenceOrder.Account = account;
                        }
                        else
                            account = _sequenceOrder.Account;

                        if (txtCardNumber.Text.Trim() != account.GetAccountNumber(_context))
                            account.SetAccountNumber(_context, txtCardNumber.Text);
                        if (txtCardExpiration.Text.Trim() != (account.CardExpiration ?? string.Empty).Trim())
                            account.CardExpiration = txtCardExpiration.Text.Trim();
                    }

                    foreach (RepeaterItem item1 in repeater1.Items)
                    {
                        foreach (RepeaterItem item2 in ((Repeater)item1.FindControl("repeater2")).Items)
                        {
                            HiddenField txtSequenceStepID = (HiddenField)item2.FindControl("txtSequenceStepID");
                            TextBox txtSequenceDelay = (TextBox)item2.FindControl("txtSequenceDelay");
                            TextBox txtSequenceTerm = (TextBox)item2.FindControl("txtSequenceTerm");
                            TextBox txtNextTriggerDate = (TextBox)item2.FindControl("txtNextTriggerDate");
                            TextBox txtShipping = (TextBox)item2.FindControl("txtShipping");
                            int sequenceOrderStepID = int.Parse(txtSequenceStepID.Value);

                            tblSequenceOrderStep sequenceOrderStep = _context.tblSequenceOrderStep.Find(new object[] { sequenceOrderStepID });
                            if (sequenceOrderStep != null)
                            {
                                short delay = sequenceOrderStep.Delay;
                                short.TryParse(txtSequenceDelay.Text, out delay);
                                sequenceOrderStep.Delay = delay;
                                short term = sequenceOrderStep.RecurrenceTerm;
                                short.TryParse(txtSequenceTerm.Text, out term);
                                sequenceOrderStep.RecurrenceTerm = term;
                                DateTime dtNextDate;
                                if (DateTime.TryParse(txtNextTriggerDate.Text, out dtNextDate))
                                    if (sequenceOrderStep.NextTriggerDate != null && sequenceOrderStep.NextTriggerDate.Value.Date != dtNextDate)
                                        sequenceOrderStep.NextTriggerDate = dtNextDate;
                                decimal shipping = 0;
                                decimal.TryParse(txtShipping.Text, out shipping);
                                if (sequenceOrderStep.Shipping != null || shipping != 0)
                                    sequenceOrderStep.Shipping = shipping;

                                foreach (RepeaterItem item3 in ((Repeater)item2.FindControl("repeater3")).Items)
                                {
                                    HiddenField txtSequenceOrderStepProductID = (HiddenField)item3.FindControl("txtSequenceOrderStepProductID");
                                    TextBox txtSequenceProductDiscount = (TextBox)item3.FindControl("txtSequenceProductDiscount");
                                    TextBox txtSequenceProductQty = (TextBox)item3.FindControl("txtSequenceProductQty");
                                    int sequenceOrderStepProductID = int.Parse(txtSequenceOrderStepProductID.Value);

                                    tblSequenceOrderStepProduct sequenceOrderStepProduct =
                                        _context.tblSequenceOrderStepProduct.Find(new object[] { sequenceOrderStepProductID });
                                    int qty;
                                    if (int.TryParse(txtSequenceProductQty.Text, out qty))
                                        sequenceOrderStepProduct.Qty = qty;
                                    sequenceOrderStepProduct.DisplayDiscount = txtSequenceProductDiscount.Text;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                ddSequenceList.DataSource = (from c in _context.tblSequence where c.OwnerID == _customer.OwnerID select c).ToArray();
                ddSequenceList.DataTextField = "Description";
                ddSequenceList.DataValueField = "SequenceID";
            }
        }

        public new void Load(SalesManagerEntities context, tblCustomer customer)
        {
            _context = context;
            _customer = customer;
            _sequenceOrderList = _context.tblSequenceOrder.Local.Where(c=>c.CustomerID == _customer.CustomerID).OrderBy(o=>o.SequenceOrderID).ToArray();

            if (!IsPostBack || (Request.Params["__EVENTARGUMENT"] == "UpdateDetails"))
            {
                lvSequenceList.DataSource = _sequenceOrderList;

                if (_sequenceOrderList.Count() > 0 && lvSequenceList.SelectedIndex < 0)
                    lvSequenceList.SelectedIndex = 0;
                if (lvSequenceList.SelectedIndex >= 0)
                    _sequenceOrder = _sequenceOrderList[lvSequenceList.SelectedIndex];

                lvSequenceList.DataBind();

                SetSteps(false);

                ddCancelReason.DataSource = (from c in _context.codeCanceledReasons where c.Active select c).ToArray();
                ddCancelReason.DataTextField = "Description";
                ddCancelReason.DataValueField = "CanceledReasonID";
                ddCancelReason.DataBind();
            }
        }

        protected void SequenceListSelectedIndexChanging(object sender, ListViewSelectEventArgs e)
        {
            lvSequenceList.SelectedIndex = e.NewSelectedIndex;
            if (lvSequenceList.SelectedIndex >= 0)
                _sequenceOrder = _sequenceOrderList[lvSequenceList.SelectedIndex];
            lvSequenceList.DataSource = _sequenceOrderList;
            lvSequenceList.DataBind();
            SetSteps(true);
        }

        public void SetSteps(bool forceUpdate)
        {
            if (_sequenceOrder != null)
            {
                List<SequenceStepPosition> steps = new List<SequenceStepPosition>();

                AddSteps(steps, _sequenceOrder.SequenceOrderSteps.Where(p => p.PrevSequenceOrderStep == null), 0);

                // Count the rows and columns required
                int rowCount = 1;
                int lastLevel = 0;
                int colCount = 0;
                foreach (SequenceStepPosition ssp in steps)
                {
                    if (ssp.Position + 1 > colCount)
                        colCount = ssp.Position + 1;
                    if (ssp.Position < lastLevel)
                        rowCount++;
                    lastLevel = ssp.Position;
                }

                // Allocate an array for the rows
                _stepArray = new tblSequenceOrderStep[rowCount][];
                for (int i = 0; i < rowCount; i++)
                    _stepArray[i] = new tblSequenceOrderStep[colCount];
                lastLevel = 0;
                rowCount = 0;
                foreach (SequenceStepPosition ssp in steps)
                {
                    if (ssp.Position < lastLevel)
                        rowCount++;
                    lastLevel = ssp.Position;
                    _stepArray[rowCount][ssp.Position] = ssp.SequenceOrderStep;
                }

                repeater1.DataSource = _stepArray;
                repeater1.DataBind();

                txtCardNumber.Enabled = true;
                txtCardExpiration.Enabled = true;
                if (_sequenceOrder.Account != null)
                {
                    txtCardNumber.Text = _sequenceOrder.Account.GetAccountNumber(_context);
                    txtCardExpiration.Text = _sequenceOrder.Account.CardExpiration;
                }
                else
                {
                    txtCardNumber.Text = string.Empty;
                    txtCardExpiration.Text = string.Empty;
                }

                btnCancel.Enabled = (_sequenceOrder.SequenceStatusCode == "I" || _sequenceOrder.SequenceStatusCode == "A");
            }
            else
            {
                btnCancel.Enabled = false;
                txtCardNumber.Enabled = false;
                txtCardExpiration.Enabled = false;
            }
        }

        private void AddSteps( List<SequenceStepPosition> stepList,
            IEnumerable<tblSequenceOrderStep> steps,
            int level)
        {
            foreach (tblSequenceOrderStep step in steps)
            {
                stepList.Add(new SequenceStepPosition(step, level));
                AddSteps(stepList, _context.tblSequenceOrderStep.Local.Where(t=>t.PrevSequenceOrderStep == t), level + 1);
            }
        }

        protected void btnCancelOK_Click(object sender, EventArgs e)
        {
            if (_sequenceOrder != null)
            {
                _context.spCancelSequence(_sequenceOrder.SequenceOrderID, int.Parse(ddCancelReason.SelectedValue));

                // Reload the SequenceOrder
                _context.Entry<tblSequenceOrder>(_sequenceOrder).Reload();

                // Trigger the Sequence panel to refresh.            
                if (!Page.ClientScript.IsStartupScriptRegistered("PostBack"))
                    Page.ClientScript.RegisterStartupScript(this.GetType(), "PostBack",
                        "<script  language='javascript' type='text/javascript'>" +
                        "__doPostBack('" + UpdatePanelSequences.UniqueID + "', 'UpdateDetails');" +
                        "</script>"
                        );
            }
        }

        protected void btnAddOK_Click(object sender, EventArgs e)
        {
            // Create a new SequenceOrder based on the selected sequence with OrderID being NULL.
            _context.spCreateSequenceOrder(_customer.CustomerID, null, int.Parse(ddSequenceList.SelectedValue));

            // Trigger the Sequence panel to refresh.            
            if (!Page.ClientScript.IsStartupScriptRegistered("PostBack"))
                Page.ClientScript.RegisterStartupScript(this.GetType(), "PostBack",
                    "<script  language='javascript' type='text/javascript'>" +
                    "__doPostBack('" + UpdatePanelSequences.UniqueID + "', 'UpdateDetails');" +
                    "</script>"
                    );
        }

        // Remove a SequenceOrderStepProduct from the list of products for a sequence.
        protected void btnRemove_Click(object sender, CommandEventArgs e)
        {
            int key = int.Parse(e.CommandArgument.ToString());

            _context.tblSequenceOrderStepProduct.Remove(_context.tblSequenceOrderStepProduct.Find(new object[] {key}));

            SetSteps(true);
        }

        // Validate the the entered expiration date is in a valid format and it current.
        protected void OnValidateExpiration(object source, ServerValidateEventArgs args)
        {
            args.IsValid = true;
            try
            {
                DateTime dt = DateTime.Now;
                if (args.Value.Trim() != string.Empty)
                    dt = DateTime.ParseExact(args.Value.Trim(), "MMyy", System.Globalization.CultureInfo.CurrentCulture);
            }
            catch (Exception)
            {
                args.IsValid = false;
            }
        }
    }

    class SequenceStepPosition
    {
        public tblSequenceOrderStep SequenceOrderStep;
        public int Position;

        public SequenceStepPosition( tblSequenceOrderStep _step, int _position )
        {
            SequenceOrderStep = _step;
            Position = _position;
        }
    }
}